perm filename GETDIR.OLD[HST,NET] blob sn#727526 filedate 1983-09-23 generic text, type C, neo UTF8
COMMENT ⊗   VALID 00008 PAGES
C REC  PAGE   DESCRIPTION
C00001 00001
C00002 00002		TITLE GETDIR  A B C D E P PDLEN BUFLEN DIN DOUT PUPVER PUPEFT IODEND VERLSN VERSTS VERTRM VERCON VCNSTS VERHST EFTGEN EFTGSK EFTLSN EFTSTS EFTLSK EFTHST DIRFIL DIRPPN DIRHLN DIRHDR VERPTR PUPMAX PKTBUF PKTLEN PKTTYP PKTDST PKTSRC PKTBFD PUPOVH OURHST PUPDSV PUPMSV PUPMHS PDL DIBUF DOBUF PUPIBF
C00007 00003	Temporary defs
C00008 00004	 DECOUT OCTOUT OCTOU1
C00009 00005	 RDPDIR
C00010 00006	 GETVER GETVE1
C00014 00007	 GNPDIR GNPDI1 GNPDI2 GNPDI3
C00020 00008	 TOPLEV NONEWP GETDIR
C00022 ENDMK
C⊗;
	TITLE GETDIR ;⊗ A B C D E P PDLEN BUFLEN DIN DOUT PUPVER PUPEFT IODEND VERLSN VERSTS VERTRM VERCON VCNSTS VERHST EFTGEN EFTGSK EFTLSN EFTSTS EFTLSK EFTHST DIRFIL DIRPPN DIRHLN DIRHDR VERPTR PUPMAX PKTBUF PKTLEN PKTTYP PKTDST PKTSRC PKTBFD PUPOVH OURHST PUPDSV PUPMSV PUPMHS PDL DIBUF DOBUF PUPIBF

;Program to get the latest PUP network directory.

A←1
B←2
C←3
D←4
P←17
PDLEN←←20
BUFLEN←←40			;Length of various blocks

DIN←←3				;Disk input channel
DOUT←←4				;Disk output channel
PUPVER←←7			;PUP channel for version request
PUPEFT←←10			;PUP channel for EFTP directory update

IODEND←←20000			;I/O status bit for end of input

PRFHST←←<50⊗=8>+313		;Ethernet address of preferred host (Navajo)
VERLSN:	1			;Listen block for PUP version request
VERSTS:	0			;Status bits returned
	-1			;Local socket
	0			;Don't wait
	=8			;Byte size
	4			;Foreign socket (misc services)
	-1			;Foreign host (broadcast)

VERTRM:	3			;Terminate block for PUPVER
	0			;Status
	0			;Local socket
	0			;Don't wait

VERCON:	0			;Connect block for PUPVER
VCNSTS:	0			;Status
	-1			;Local socket
	-1			;Do wait (though in packet mode we won't)
	=8			;Byte size
	4			;Foreign socket
VERHST:	0			;Foreign host

EFTGEN:	21			;Gensym block for EFTP socket
EFTGSK:	0

EFTLSN:	1			;Listen block for EFTP
EFTSTS:	0			;Status bits returned
EFTLSK:	0			;Local socket
	0			;Don't wait
	=8			;Byte size
	-1			;Foreign socket (whatever they choose)
EFTHST:	0			;Foreign host

DIRFIL:	SIXBIT/PUPNET/		;LOOKUP/ENTER block for PUP network directory
	SIXBIT/TMP/		;(eventually DIR)
	0
	0
DIRPPN:	SIXBIT/HSTNET/

DIRHLN←←4			;Number of header words to read from file
DIRHDR:	BLOCK DIRHLN
VERPTR:	POINT 16,DIRHDR+3,15	;Byte ptr for version number
PUPMAX←←=140			;Maximum PUP packet length
PKTBUF:	BLOCK PUPMAX		;PUP packet buffer
;Pointers into PKTBUF
PKTLEN:	POINT 16,PKTBUF,15	;PUP length (in bytes)
PKTTYP:	POINT 16,PKTBUF,31	;PUP Type
PKTDST:	POINT 16,PKTBUF+2,15	;PUP Destination host
PKTSRC:	POINT 16,PKTBUF+3,31	;PUP Source host
PKTBFD←←PKTBUF+5		;Location of data within PUP
PUPOVH←←=22			;Number of overhead bytes in a PUP

OURHST:	BLOCK 1			;Our PUP address (from an incoming packet)
PUPDSV:	BLOCK 1			;PUP directory on disk's version number
PUPMSV:	BLOCK 1			;Highest version number from misc. servers
PUPMHS:	BLOCK 1			;Host number that has highest version

PDL:	BLOCK PDLEN
DIBUF:	BLOCK 3			;Buffer headers
DOBUF:	BLOCK 3
PUPIBF:	BLOCK 3

DEFINE MESSAG(MESS) <
	JRST [  MOVEI A,[ASCIZ\MESS
\]
		JRST MESTYP]
>
;Temporary defs

MESTYP:	OUTSTR [ASCIZ/Here at MESTYP, you loser.
/]
	HALT CPOPJ

CPOPJ1:	AOS (P)
CPOPJ:	POPJ P,

CRLF:	BYTE (7)15,12
;⊗ DECOUT OCTOUT OCTOU1

DECOUT:	SKIPA C,[=10]
OCTOUT:	MOVEI C,=8
OCTOU1:	IDIVI A,(C)
	HRLM B,(P)
	JUMPE A,.+2
	PUSHJ P,OCTOU1
	HLRZ B,(P)
	ADDI B,"0"
	OUTCHR B
	POPJ P,
;⊗ RDPDIR

;Here to read saved version number from PUP network directory on disk.  Call:
;	PUSHJ P,RDPDIR
;	<error return>
;	<success, version number in PUPDSV>
RDPDIR:	INIT DIN,17		;Open disk input in dump mode
	 SIXBIT/DSK/
	 0
	 MESSAGE INIT error for PUP network directory input.
	MOVE A,DIRPPN
	MOVEM A,DIRFIL+3
	LOOKUP DIN,DIRFIL
	 JRST CPOPJ1		;Just return if no file
	IN DIN,[IOWD DIRHLN,DIRHDR ↔ 0]	;Read the header
	 CAIA
	MESSAGE Input error for PUP network directory
	LDB A,VERPTR		;Get version number
	MOVEM A,PUPDSV		;Store as disk version number
	JRST CPOPJ1
;⊗ GETVER GETVE1

;Here to get version number from misc servers on the Ethernet.  Assumes
;our version number is already in PUPDSV.  Call:
;	PUSHJ P,GETVER
;	<error return>
;	<success, highest version number in PUPMSV, host in PUPMHS>
GETVER:	MOVE A,PUPDSV		;Our version
	MOVEM A,PUPMSV		;Is best so far
	INIT PUPVER,15		;Packet mode
	 SIXBIT/PUP/
	 0			;No buffers
	 MESSAG INIT error for PUP version request.
	MTAPE PUPVER,VERLSN	;Listen
	SKIPE VERSTS
	 MESSAG Error in LISTEN MTAPE for PUP version request.
	SETZM PKTBUF		;Clear out old header, so WAITS fills this
	MOVE A,[PKTBUF,,PKTBUF+1] ;stuff in.
	BLT A,PKTBFD
	MOVEI A,240		;Set packet type to NetDirVersion
	DPB A,PKTTYP
	MOVE A,PUPDSV		;Get our version number
	DPB A,[POINT 16,PKTBFD,15] ;Store in packet
	MOVEI A,PUPOVH+2	;Length = overhead + 2 data bytes
	DPB A,PKTLEN
	ADDI A,2+2+3		;Plus Ethernet header plus rounding
	LSH A,-2		;Convert to words
	HRLOI A,-1(A)		;<len-1>,,-1
	EQVI A,PKTBUF-1		;<-len>,,PKTBUF-1
	SETZ B,			;End IOWD list
	OUT PUPVER,A		;Send the packet
	 CAIA
	MESSAG Error in PUP version request output.
	MOVEI C,5		;Number of seconds to wait for replies
	MOVEI D,1
GETVE1:	MTAPE PUPVER,[10]	;Skip if input available
	 JRST [	SOJL C,CPOPJ1	;We can't wait forever
		SLEEP D,	;Wait one second
		JRST GETVE1]	;Try again
	IN PUPVER,[IOWD PUPMAX,PKTBUF ↔ 0] ;Read packet
	 CAIA
	MESSAG Input error in PUP version reply.
	LDB A,PKTTYP		;Check reply type
	LDB B,[POINT 16,PKTBFD,15] ;And version number
	CAIN A,240		;NetDirVersion?
	CAMGE B,PUPMSV		;At least as good as best so far?
	JRST GETVE1		;No, ignore it
	LDB A,PKTSRC		;Get source of this reply
	CAIE A,PRFHST		;Is this the preferred host?
	CAMLE B,PUPMSV		;No.  Then we want a higher version number
	CAIA			;Preferred host or higher than current version
	JRST GETVE1		;Reject this one
	MOVEM A,PUPMHS		;Save host number
	MOVEM B,PUPMSV		;This is the best version now
	LDB A,PKTDST		;Get our own address while we're at it
	MOVEM A,OURHST		;We'll need it later
	JRST GETVE1		;Keep trying until tired
;⊗ GNPDIR GNPDI1 GNPDI2 GNPDI3

;Here to get new PUP network directory from host in PUPMHS.  Call:
;	PUSHJ P,GNPDIR
;	<error return>
;	<success return>
GNPDIR:	INIT PUPEFT,13		;EFTP mode
	 SIXBIT/PUP/
	 0,,PUPIBF
	 MESSAG INIT failure for EFTP channel.
	MOVEI A,=8		;Change byte size
	DPB A,[POINT 6,PUPIBF+1,11] ;in buffer header
	INBUF PUPEFT,2		;Set up buffer ring
	MOVE A,PUPMHS		;Set host number in MTAPE blocks
	MOVEM A,VERHST
	MOVEM A,EFTHST
	MTAPE PUPEFT,EFTGEN	;Gensym a socket for EFTP
	MOVE A,EFTGSK		;Copy into listen block
	MOVEM A,EFTLSK
	MTAPE PUPEFT,EFTLSN	;Listen on EFTP channel
	SKIPE EFTSTS		;Check status bits
	 MESSAG Error in LISTEN MTAPE for PUP directory update.
	MTAPE PUPVER,VERTRM	;Close previous connection on PUPVER
	MTAPE PUPVER,VERCON	;Get new connection to this host
	SKIPE VCNSTS
	 MESSAG Error in CONNECT MTAPE for PUP directory update.
	SETZM PKTBUF		;Clear out old header, so WAITS fills this
	MOVE A,[PKTBUF,,PKTBUF+1] ;stuff in.
	BLT A,PKTBFD
	MOVEI A,241		;Packet type SendNetDir
	DPB A,PKTTYP
	MOVE A,OURHST			;Our host number
	DPB A,[POINT 16,PKTBFD,15]	;is first part of port number
	MOVE A,EFTGSK			;EFTP socket
	DPB A,[POINT 16,PKTBFD+1,15]	;is the rest
	LSH A,-=16
	DPB A,[POINT 16,PKTBFD,31]
	MOVEI A,PUPOVH+6	;Length = overhead + 6 data bytes
	DPB A,PKTLEN
	ADDI A,2+2+3		;Plus Ethernet header plus rounding
	LSH A,-2		;Convert to words
	HRLOI A,-1(A)		;<len-1>,,-1
	EQVI A,PKTBUF-1		;<-len>,,PKTBUF-1
	SETZ B,			;End IOWD list
	OUT PUPVER,A		;Send the packet
	 CAIA
	MESSAG Error in PUP directory request output.
	RELEAS PUPVER,		;Done with version request channel
	;Now EFTP the directory into core.
	MOVE A,JOBFF↑
	PUSHJ P,GETCOR		;Clear core, set D to bytes cleared
	HRRZ B,JOBFF↑		;Start storing here
	HRLI B,(<POINT 8,0>)	;Make byte ptr to IDPB
GNPDI1:	SOSG PUPIBF+2		;See if there's more EFTP input
	IN PUPEFT,
	 JRST GNPDI2		;Yes, there is
	STATO PUPEFT,IODEND	;End of input?
	 MESSAG Error in PUP directory input.
	JRST GNPDI3		;Yes

GNPDI2:	SOJGE D,GNPDI4		;Jump if there's room for this byte
	MOVEI A,1(B)		;No room.  Get address of next word to store
	PUSHJ P,GETCOR		;Get and clear some core
	SOS D			;Fix byte count
GNPDI4:	ILDB A,PUPIBF+1		;Load byte
	IDPB A,B		;Store byte
	JRST GNPDI1		;Continue copying

GNPDI3:	RELEAS PUPEFT,		;All done with EFTP channel
	INIT DOUT,17		;OPEN disk output channel in dump mode
	 SIXBIT/DSK/
	 0
	 MESSAG Disk INIT failure in writing PUP directory.
	MOVE A,DIRPPN		;Set up ENTER block
	MOVEM A,DIRFIL+3
	ENTER DOUT,DIRFIL	;Enter directory file
	 MESSAG ENTER error in writing PUP directory.
	HRRZ A,JOBFF↑		;Addr of start of data
	SUBI A,1		;-1 for IOWD
	SUBM A,B		;-<word count> in RH(B)
	HRL A,B			;Make IOWD
	SETZ B,			;End IOWD list
	OUT DOUT,A		;Do dump mode output
	 CAIA
	MESSAGE Output error in writing PUP directory file.
	JRST CPOPJ1		;All done, hooray!

;Here to clear core and expand if necessary.
;Call:	MOVE A,<starting address of core to clear>
;	PUSHJ P,GETCOR
;	<return with core cleared from (A) to JOBREL, byte count in D>
GETCOR:	CAMGE A,JOBREL↑		;Need more core?
	JRST GETCO1		;No.  (Must be first call to GETCOR)
	MOVEI D,1777(A)		;Yes, get 2 pages
	CORE D,
	 MESSAG CORE UUO failed in PUP directory input.
GETCO1:	SETZM (A)		;Zero first word
	MOVEI D,1(A)		;Make BLT word
	HRLI D,(A)
	BLT D,@JOBREL↑		;Clear core
	MOVE D,JOBREL↑
	SUBI D,-1(A)		;Count of words gotten
	LSH D,2			;Times 4 for 8-bit bytes
	POPJ P,
;⊗ TOPLEV NONEWP GETDIR

TOPLEV:	PUSHJ P,RDPDIR		;Read version from PUP directory on disk
	 POPJ P,		;Error
	OUTSTR [ASCIZ/Our PUP network directory is version /]
	MOVE A,PUPDSV
	PUSHJ P,OCTOUT
	OUTSTR CRLF
	PUSHJ P,GETVER		;Get version from misc servers
	 POPJ P,		;Error of some kind
	MOVE A,PUPMSV		;Highest version reported
	CAMG A,PUPDSV		;Compare with our version
	 JRST NONEWP		;No new PUP directory
	OUTSTR [ASCIZ/Getting new PUP directory version /]
	PUSHJ P,OCTOUT		;Output version in A
	OUTSTR [ASCIZ/ from host /]
	LDB A,[POINT 8,PUPMHS,27]
	PUSHJ P,OCTOUT		;Subnet
	OUTCHR ["#"]
	LDB A,[POINT 8,PUPMHS,35]
	PUSHJ P,OCTOUT		;Host
	OUTSTR CRLF
	PUSHJ P,GNPDIR		;Get new PUP directory
	 POPJ P,		;Some error
	OUTSTR [ASCIZ/New PUP directory successfully installed.
/]
	EXIT

NONEWP:	OUTSTR [ASCIZ/No update of PUP network directory needed.
/]
	EXIT


GETDIR:	RESET			;Program starts here
	MOVE P,[IOWD PDLEN,PDL]
	PUSHJ P,TOPLEV		;Only returns if some kind of error
	EXIT

	END GETDIR